namespace TSL.Utility.Json
{
    using System;
    using System.Reflection;
    using System.Text;

    public sealed class JavaScriptSerializer
    {
        public static string Serialize(object o)
        {
            StringBuilder sb = new StringBuilder();
            Serialize(o, sb);
            return sb.ToString();
        }

        public static void Serialize(object o, StringBuilder sb)
        {
            if ((o == null) || (o is DBNull))
            {
                sb.Append("null");
            }
            else
            {
                IJavaScriptConverter converter = null;
                Type key = o.GetType();
                if (Utility.Settings.SerializableConverters.TryGetValue(key, out converter))
                {
                    converter.Serialize(o, sb);
                }
                else
                {
                    foreach (IJavaScriptConverter converter2 in Utility.Settings.SerializableConverters.Values)
                    {
                        if (converter2.TrySerializeValue(o, key, sb))
                        {
                            return;
                        }
                    }
                    try
                    {
                        SerializeCustomObject(o, sb);
                    }
                    catch (StackOverflowException)
                    {
                        throw new Exception("AjaxPro stack overflow exception while trying to serialize type '" + key.Name + "'.");
                    }
                }
            }
        }

        [Obsolete("The recommended alternative is JavaScriptSerializer.SerializeCustomObject(object, StringBuilder).", true)]
        internal static string SerializeCustomObject(object o)
        {
            StringBuilder sb = new StringBuilder();
            SerializeCustomObject(o, sb);
            return sb.ToString();
        }

        internal static void SerializeCustomObject(object o, StringBuilder sb)
        {
            Type type = o.GetType();
            bool flag = false;
            bool flag2 = false;
            foreach (object obj2 in type.GetCustomAttributes(true))
            {
                if (obj2 is AjaxNonSerializableAttribute)
                {
                    flag = true;
                }
                else if (obj2 is AjaxNoTypeUsageAttribute)
                {
                    flag2 = true;
                }
            }
            bool flag3 = true;
            sb.Append('{');
            if (!flag2)
            {
                flag2 = !Utility.Settings.IncludeTypeProperty;
            }
            if (!flag2)
            {
                sb.Append("\"__type\":");
                JavaScriptUtil.QuoteString(type.AssemblyQualifiedName, sb);
                flag3 = false;
            }
            foreach (FieldInfo info in type.GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                if ((!flag && !info.IsDefined(typeof(AjaxNonSerializableAttribute), true)) || (flag && info.IsDefined(typeof(AjaxPropertyAttribute), true)))
                {
                    if (!flag3)
                    {
                        sb.Append(",");
                    }
                    JavaScriptUtil.QuoteString(info.Name, sb);
                    sb.Append(':');
                    Serialize(info.GetValue(o), sb);
                    flag3 = false;
                }
            }
            foreach (PropertyInfo info2 in type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance))
            {
                MethodInfo getMethod = info2.GetGetMethod();
                if (((getMethod != null) && (getMethod.GetParameters().Length <= 0)) && ((!flag && !info2.IsDefined(typeof(AjaxNonSerializableAttribute), true)) || (flag && info2.IsDefined(typeof(AjaxPropertyAttribute), true))))
                {
                    if (!flag3)
                    {
                        sb.Append(",");
                    }
                    JavaScriptUtil.QuoteString(info2.Name, sb);
                    sb.Append(':');
                    Serialize(getMethod.Invoke(o, null), sb);
                    flag3 = false;
                }
            }
            sb.Append('}');
        }

        [Obsolete("The recommended alternative is JavaScriptUtil.QuoteString(string).", false)]
        public static string SerializeString(string s)
        {
            return JavaScriptUtil.QuoteString(s);
        }
    }
}

